package com.autoscript.web;

import com.autoscript.ISystemConstant;
import com.autoscript.ext.xmldata.dbmodel.DBModel;
import com.autoscript.ext.xmldata.dbmodel.IDBModel;
import com.autoscript.service.PublicService;
import com.autoscript.service.RunlogService;
import com.autoscript.utils.SessionMap;
import com.autoscript.utils.WebSocketList;
import com.dfhc.util.DateUtil;
import com.dfhc.util.StringHelper;
import com.dfhc.util.ConvertHelper;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.beans.factory.annotation.Autowired;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import com.autoscript.vo.ProjectVo;
import com.autoscript.service.ProjectService;

import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.multipart.MultipartFile;

/**
 * 工程表Controller
 *
 * @author lsb
 * @version 1.0.0
 * @date 2021-02-02
 */
@RestController
@CrossOrigin(allowCredentials = "true", allowedHeaders = "*")
@RequestMapping(value = "/api/Project")
public class ProjectController {
    private static Logger logger = LoggerFactory.getLogger(ProjectController.class);
    /**
     * 工程表服务
     */
    @Autowired
    private ProjectService projectService;
    @Autowired
    private PublicService publicService;
    @Autowired
    private WebSocketList webSocketList;
    @Autowired
    private SessionMap sessionMap;
    /**
     * 新增工程表
     * ProjectVo  工程表VO
     *
     * @return Map
     */
    @RequestMapping(value = "insert", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
    @ResponseBody
    public Map<String, Object> insert(HttpServletRequest request, @RequestBody ProjectVo projectVo) {
        Map<String, Object> result = new HashMap<String, Object>();
        try {
            //插入工程表(含校验)
            //初始化创建用户id，创建时间
            Map<String,Object> hSessionMap = sessionMap.get(request.getHeader(ISystemConstant.SESSION_ID));
            if(hSessionMap==null){
                result.put(ISystemConstant.AJAX_STATUS, ISystemConstant.AJAX_RESULT_FAIL);
                result.put(ISystemConstant.AJAX_MESSAGE, "尚未登录系统!");
                return result;
            }

            Map userMap = (Map) hSessionMap.get(ISystemConstant.CURRENT_USER);
            if (userMap != null) {
                projectVo.setCreateUserId((String) userMap.get("ID"));
            }

            projectVo.setCreateDate(DateUtil.getNowDate("yyyy-MM-dd"));
            projectService.insert(projectVo);
            result.put(ISystemConstant.AJAX_STATUS, ISystemConstant.AJAX_RESULT_SUCCESS);
            result.put(ISystemConstant.AJAX_MESSAGE, "工程表成功!");
        } catch (Exception e) {
            logger.error("工程表失败", e);
            result.put(ISystemConstant.AJAX_STATUS, ISystemConstant.AJAX_RESULT_FAIL);
            result.put(ISystemConstant.AJAX_MESSAGE, e.getMessage());
        }
        return result;
    }

    /**
     * 更新工程表
     * ProjectVo  工程表VO
     *
     * @return Map
     */
    @RequestMapping(value = "update", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
    @ResponseBody
    public Map<String, Object> update(HttpServletRequest request, @RequestBody ProjectVo projectVo) {
        Map<String, Object> result = new HashMap<String, Object>();
        try {
            //更新工程表(含校验)
            projectService.update(projectVo);
            result.put(ISystemConstant.AJAX_STATUS, ISystemConstant.AJAX_RESULT_SUCCESS);
            result.put(ISystemConstant.AJAX_MESSAGE, "工程表成功!");
        } catch (Exception e) {
            logger.error("工程表失败", e);
            result.put(ISystemConstant.AJAX_STATUS, ISystemConstant.AJAX_RESULT_FAIL);
            result.put(ISystemConstant.AJAX_MESSAGE, e.getMessage());
        }
        return result;
    }

    /**
     * 删除工程表
     * ProjectVo  工程表VO
     *
     * @return Map
     */
    @RequestMapping(value = "delete", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
    @ResponseBody
    public Map<String, Object> delete(HttpServletRequest request, @RequestBody ProjectVo projectVo) {
        Map<String, Object> result = new HashMap<String, Object>();
        try {
            //更新工程表(含校验)
            projectService.delete(projectVo);
            result.put(ISystemConstant.AJAX_STATUS, ISystemConstant.AJAX_RESULT_SUCCESS);
            result.put(ISystemConstant.AJAX_MESSAGE, "工程表成功!");
        } catch (Exception e) {
            logger.error("工程表失败", e);
            result.put(ISystemConstant.AJAX_STATUS, ISystemConstant.AJAX_RESULT_FAIL);
            result.put(ISystemConstant.AJAX_MESSAGE, e.getMessage());
        }
        return result;
    }

    /**
     * 根据id查询工程表
     *
     * @return Map<String   ,       Object>  应答Map
     */
    @RequestMapping(value = "getById", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
    @ResponseBody
    public Map<String, Object> getById(HttpServletRequest request) {
        Map<String, Object> result = new HashMap<String, Object>();
        try {
            String id = request.getParameter("id");
            Map m = projectService.getById(id);

            //返回
            if (m == null) {
                result.put(ISystemConstant.AJAX_STATUS, ISystemConstant.AJAX_RESULT_FAIL);
                result.put(ISystemConstant.AJAX_MESSAGE, "工程表数据没找到!");
            } else {
                result.put(ISystemConstant.AJAX_BEAN, m);
                result.put(ISystemConstant.AJAX_MESSAGE, "操作成功!");
                result.put(ISystemConstant.AJAX_STATUS, ISystemConstant.AJAX_RESULT_SUCCESS);
            }
        } catch (Exception e) {
            logger.error("getById失败", e);
            result.put(ISystemConstant.AJAX_STATUS, ISystemConstant.AJAX_RESULT_FAIL);
            result.put(ISystemConstant.AJAX_MESSAGE, "查询工程表数据失败!");
        }
        return result;

    }

    /**
     * 翻页查询工程表列表
     *
     * @param request
     * @return Map<String   ,       Object> 查询列表应答Map
     */
    @RequestMapping(value = "listPage", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
    @ResponseBody
    public Map<String, Object> listPage(HttpServletRequest request) {
        Map<String, Object> result = new HashMap<String, Object>();
        try {
            //TODO:获取查询条件
//            String userId = request.getParameter("userId");
//            if (StringHelper.isEmpty(userId))
//                throw new Exception("缺少参数:userId");
            //页号
            String strPageNo = request.getParameter(ISystemConstant.PAGE_NO);
            if (StringHelper.isEmpty(strPageNo))
                throw new Exception("缺少参数:" + ISystemConstant.PAGE_NO);
            //页大小
            String strPageSize = request.getParameter(ISystemConstant.PAGE_SIZE);
            if (StringHelper.isEmpty(strPageSize))
                throw new Exception("缺少参数:" + ISystemConstant.PAGE_SIZE);

            int pageNo = ConvertHelper.toInt(strPageNo);
            int pageSize = ConvertHelper.toInt(strPageSize);
            List<Map> list;
            logger.info("pageNo:" + pageNo);
            logger.info("pageSize:" + pageSize);
            Map<String, Object> searchMap;
            searchMap = new HashMap<String, Object>();
            //TODO 拼装条件
//            searchMap.put("CREATE_USER_ID", userId);
            list = projectService.listPage(searchMap, pageNo, pageSize);
            logger.info("list count:" + list.size());
            result.put(ISystemConstant.AJAX_STATUS, ISystemConstant.AJAX_RESULT_SUCCESS);
            result.put(ISystemConstant.AJAX_LIST, list);
            result.put("count", projectService.count(searchMap));
            result.put(ISystemConstant.AJAX_MESSAGE, "查询成功!");
        } catch (Exception e) {
            logger.error("工程表查询失败,参数为:" + request.getParameter("userId"), e);
            result.put(ISystemConstant.AJAX_STATUS, ISystemConstant.AJAX_RESULT_FAIL);
            result.put(ISystemConstant.AJAX_MESSAGE, e.getMessage());
        }
        return result;
    }

    /**
     * 上传文件(目前仅支持pdm文件)
     *
     * @param request
     * @return Map<String   ,       Object> pdm包含的数据库表列表Map
     */
    @RequestMapping(value = "uploadPdmFile", method = RequestMethod.POST)
    @ResponseBody
    public Map<String, Object> uploadPdmFile(HttpServletRequest request,@RequestParam("filename") MultipartFile file) {
        logger.info("接收到的文件名为：" + file.getOriginalFilename());
        Map<String, Object> result = new HashMap<String, Object>();
        if (file.isEmpty()) {
            result.put(ISystemConstant.AJAX_STATUS, ISystemConstant.AJAX_RESULT_FAIL);
            result.put(ISystemConstant.AJAX_MESSAGE, "上传文件为空!");
            return result;
        }
        // 尝试解析pdm文件
        try {
            List<Map<String,String>> tableList;
            tableList = projectService.parsePdm(request,file.getBytes());
            result.put(ISystemConstant.AJAX_LIST,tableList);
            result.put(ISystemConstant.AJAX_STATUS, ISystemConstant.AJAX_RESULT_SUCCESS);
            result.put(ISystemConstant.AJAX_MESSAGE, "解析文件成功!");
            return result;
        } catch (Exception e) {
            logger.error("文件解析错误",e);
            result.put(ISystemConstant.AJAX_STATUS, ISystemConstant.AJAX_RESULT_FAIL);
            result.put(ISystemConstant.AJAX_MESSAGE, "解析文件失败!");
            return result;
        }
    }

    /**
     * 导入工程zip
     *
     * @param request
     * @return 导入结果
     */
    @RequestMapping(value = "import", method = RequestMethod.POST)
    @ResponseBody
    public Map<String, Object> importProject(HttpServletRequest request,@RequestParam("filename") MultipartFile file) {
        logger.info("接收到的文件名为：" + file.getOriginalFilename());
        Map<String, Object> result = new HashMap<String, Object>();
        if (file.isEmpty()) {
            result.put(ISystemConstant.AJAX_STATUS, ISystemConstant.AJAX_RESULT_FAIL);
            result.put(ISystemConstant.AJAX_MESSAGE, "上传文件为空!");
            return result;
        }
        // 尝试导入文件
        try {
            projectService.importProject(request,file.getBytes());
            result.put(ISystemConstant.AJAX_STATUS, ISystemConstant.AJAX_RESULT_SUCCESS);
            result.put(ISystemConstant.AJAX_MESSAGE, "导入工程成功!");
            return result;
        } catch (Exception e) {
            logger.error("导入工程错误",e);
            result.put(ISystemConstant.AJAX_STATUS, ISystemConstant.AJAX_RESULT_FAIL);
            result.put(ISystemConstant.AJAX_MESSAGE, "导入工程失败!");
            return result;
        }
    }


    /**
     * 执行工程生成代码
     *
     * @param request
     * @return Map<String,Object> 查询列表应答Map
     */
    @RequestMapping(value = "run", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
    @ResponseBody
    public Map<String, Object> run(HttpServletRequest request,@RequestBody Map<String,String> projectParameter) {
        Map<String, Object> result = new HashMap<String, Object>();
        //debug
        Map<String,Object> hSessionMap = sessionMap.get(request.getHeader(ISystemConstant.SESSION_ID));
        if(hSessionMap==null){
            result.put(ISystemConstant.AJAX_STATUS, ISystemConstant.AJAX_RESULT_FAIL);
            result.put(ISystemConstant.AJAX_MESSAGE, "请重新登录!");
            return result;
        }
        DBModel dbModel = (DBModel)hSessionMap.get(ISystemConstant.PDM_MODEL);
        //获取选择表
        String[] tableCodes = request.getParameter("tableCode").split(",");
        if(tableCodes==null || tableCodes.length==0){
            result.put(ISystemConstant.AJAX_STATUS, ISystemConstant.AJAX_RESULT_FAIL);
            result.put(ISystemConstant.AJAX_MESSAGE, "请选择表!");
            return result;
        }
        String projectId = request.getParameter("projectId");
        if(StringHelper.isEmpty(projectId)){
            result.put(ISystemConstant.AJAX_STATUS, ISystemConstant.AJAX_RESULT_FAIL);
            result.put(ISystemConstant.AJAX_MESSAGE, "缺少项目id!");
            return result;
        }
        //产生运行日志编号
        try {
            String logCode = publicService.getIds("LOG_CODE", 1)[0];
            //String loginSession = (String)hSessionMap.get(ISystemConstant.CURRENT_APP_TOKEN);
            String httpSession = (String)hSessionMap.get(ISystemConstant.SESSION_ID);
            //启动产生代码线程
            Thread t = new Thread(() -> {
                projectService.generateCode(dbModel, tableCodes, logCode, projectId, projectParameter,httpSession);
            });
            t.start();
            result.put(ISystemConstant.AJAX_STATUS, ISystemConstant.AJAX_RESULT_SUCCESS);
            result.put(ISystemConstant.AJAX_MESSAGE, "请在运行日志查看日志编号:" + logCode + "运行进度!");
            result.put(ISystemConstant.LOG_NUMBER,logCode);
            return result;
        }catch(Exception e){
            result.put(ISystemConstant.AJAX_STATUS, ISystemConstant.AJAX_RESULT_FAIL);
            result.put(ISystemConstant.AJAX_MESSAGE, e.getMessage());
            return result;
        }
    }
    /**
     * 根据id 导出工程信息（含工程参数及下级模版列表)
     */
    @RequestMapping(value ="export" )
    public void export(HttpServletRequest request, HttpServletResponse response){
        try {
            //TODO:登录检查
            String id = request.getParameter("id");
            if (StringHelper.isEmpty(id)) {
                response.getWriter().println("缺少日志号参数!");
                return;
            }

            Map projectVo = projectService.getById(id);

            //返回
            if(projectVo==null) {
                response.getWriter().println("运行工程记录数据没找到!");
            }else {
                projectService.export(projectVo,response);
            }
        } catch (Exception e) {
            logger.error("export失败", e);
            try {
                response.getWriter().println("导出工程文件失败!");
            }catch(Exception e1){
                e1.printStackTrace();
            }
        }
    }
    /**
     * 上传sql文件
     *
     * @param request
     * @param file 文件内容
     * @param dbType 数据库类型
     * @return Map<String   ,       Object> sql包含的数据库表列表Map
     */
    @RequestMapping(value = "uploadSqlFile", method = RequestMethod.POST)
    @ResponseBody
    public Map<String, Object> uploadSqlFile(HttpServletRequest request,@RequestParam("filename") MultipartFile file,
                                             @RequestParam("dbType") String dbType) {
        logger.info("接收到的文件名为：" + file.getOriginalFilename());
        Map<String, Object> result = new HashMap<String, Object>();
        if (file.isEmpty()) {
            result.put(ISystemConstant.AJAX_STATUS, ISystemConstant.AJAX_RESULT_FAIL);
            result.put(ISystemConstant.AJAX_MESSAGE, "上传文件为空!");
            return result;
        }
        // 尝试解析sql文件
        try {
            List<Map<String,String>> tableList;
            tableList = projectService.parseSql(request,file.getBytes(),dbType);
            result.put(ISystemConstant.AJAX_LIST,tableList);
            result.put(ISystemConstant.AJAX_STATUS, ISystemConstant.AJAX_RESULT_SUCCESS);
            result.put(ISystemConstant.AJAX_MESSAGE, "解析文件成功!");
            return result;
        } catch (Exception e) {
            logger.error("文件解析错误",e);
            result.put(ISystemConstant.AJAX_STATUS, ISystemConstant.AJAX_RESULT_FAIL);
            result.put(ISystemConstant.AJAX_MESSAGE, "解析文件失败!");
            return result;
        }
    }
}
